package com.dragon.www.haier.net;

import com.dragon.www.haier.service.DevicePacketFactory;

import java.io.IOException;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * Created by Administrator on 2015/11/17 22:12.
 * Author: songxy
 * Email: thinkdata@163.com
 */
public class AppUDPPacket extends AUDPPacket implements Serializable, Cloneable {
	/**
	 *
	 */
	private final static int DATA_LENGTH = 300;
	/**
	 * 数据域变长
	 */
	protected short packetLength;
	/**
	 * 头部
	 */
	protected byte[] packetHeader;
	/**
	 * 类型
	 */
	protected byte[] packetType;
	/**
	 * 数据域
	 */
	protected byte[] packetData;
	/**
	 * 校验值
	 */
	protected byte[] packetCS;
	/**
	 * 尾部
	 */
	protected byte[] packetEnd;

	public AppUDPPacket() {
		this.packetHeader = new byte[] { (byte) 0xEE, (byte) 0xFF};
		this.packetType = new byte[2];
		this.packetCS = new byte[] { (byte) 0xEE, (byte) 0xEE };
		this.packetEnd = new byte[] { (byte) 0xFF, (byte) 0xFF };
	}

	@Override
	public void checksum() {

	}

	@Override
	public void writePacketObject(DatagramPacket packet) throws IOException, NullPointerException {
		if (packet == null) {
			throw new NullPointerException("Pls Instance OutPacket. ");
		}
		ByteBuffer bb = ByteBuffer.allocate(totalLength());
		bb.put(this.packetHeader, 0, this.packetHeader.length);
		bb.put(this.packetType, 0, this.packetType.length);
		bb.putShort(this.packetLength);
		bb.put(this.packetCS, 0, this.packetCS.length);
		bb.put(this.packetData, 0, this.packetData.length);
		bb.put(this.packetEnd, 0, this.packetEnd.length);
		checksum();
		packet.setData(bb.array());
		packet.setLength(bb.array().length);
		if (getSocketAddress() != null)
			packet.setSocketAddress(getSocketAddress());
	}

	@Override
	public void readPacketObject(ByteBuffer bb) throws IOException {
		if (this.packetLength == 0) {
			this.packetLength = bb.getShort();
			if (packetLength >= bb.capacity()) {
				this.packetData = new byte[0];
			}
		}else {
			this.packetData = new byte[this.packetLength];
			// 略过length
			bb.getShort();
		}
		this.packetCS = new byte[2];
		bb.get(this.packetCS);

		bb.get(this.packetData);
	}

	@Override
	public ByteBuffer readPacketHeader(DatagramPacket packet) throws IOException {
		if (packet == null) {
			throw new NullPointerException("Pls Instance InPacket.");
		}

		this.mSocketAddress = packet.getSocketAddress();

		ByteBuffer bb = ByteBuffer.allocateDirect(packet.getLength());
		bb.put(packet.getData(), 0, packet.getLength());
		bb.flip();
		if (this.packetHeader == null)
			this.packetHeader = new byte[4];
		bb.get(this.packetHeader);

		if (this.packetType == null)
			this.packetType = new byte[2];
		bb.get(this.packetType);

		// FIXME: 2016/3/31 0x8200丢弃
		if (Arrays.equals(this.packetType, DevicePacketFactory.KEY_ACTION_DATAGRAM_TYPE_ACTION_DETECT_2)) {
			return null;
		}
		return bb;
	}

	@Override
	public void readPacketTail(ByteBuffer bb) throws IOException {
		if (this.packetEnd == null)
			this.packetEnd = new byte[4];
		bb.get(this.packetEnd);
		checksum();
	}

	public boolean hasData() {
		return this.mPacket != null && this.mPacket.getLength() > 0;
	}

	public byte[] getStart() {
		return this.packetHeader;
	}

	public byte[] getAction() {
		return packetType;
	}

	public void setAction(byte[] action) {
		this.packetType = action;
	}

	public short getPacketDataLength() {
		return packetLength;
	}

	public void setPacketDataLength(short data1) {
		this.packetLength = data1;
	}

	public byte[] getPacketData() {
		return packetData;
	}

	public void setPacketData(byte[] data2) {
		this.packetData = data2;
	}

	public byte[] getEnd() {
		return this.packetEnd;
	}

	public byte[] getCS() {
		return packetCS;
	}

	public int totalLength() {
		//根据数据域的长度大小赋值
		int dataLen = 0;
		if (getPacketData() != null && getPacketData().length > 0) {
			dataLen = getPacketData().length;
		}else if (getPacketDataLength() > 0) {
			dataLen = getPacketDataLength();
		}else {
			dataLen = DATA_LENGTH;
		}
		return this.packetHeader.length + this.packetType.length
				+ 2 + this.packetCS.length + this.packetEnd.length + dataLen;
	}

	@Override
	public String toString() {
		return "Header(2)=[ " + Utils.byte2HexString(packetHeader)
				+ " ] Type(1)=[ " + Utils.byte2HexString(packetType)
				+ " ] Data Length(4)=[ " + Utils.byte2HexString(packetHeader)
				+ " ] CS=[ " + Utils.byte2HexString(packetCS)
				+ " ] End=[ " + Utils.byte2HexString(packetEnd) + "] .";
	}

}
